#include "My_CortexM3_Def.h"

void USART_SendData(USART_TypeDef * usart, Uint Data)
{
    usart->DR = (Data & (Uint)0x01FF);
}

FlagStatus USART_GetFlagStatus(USART_TypeDef * usart, Uint USART_FLAG)
{
    FlagStatus    bitstatus = RESET;

    if( (usart->SR & USART_FLAG) != (Uint)RESET) {
        bitstatus = SET; 
    }
    else {
         bitstatus = RESET; 
    }
     
    return bitstatus;
}

void SerialPutChar( Uchar c )
{
    USART_SendData(USART1, (Uint)c);
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}

void Serial_PutString(Uchar *s)
{
  while(*s != 0 ) {
      SerialPutChar(*s);
      s++;
  }
}

void USARTSet(USART_TypeDef *usart, USART_InitTypeDef *type)
{
    Ulong     tmp = 0x00;
    Ulong     apbclock = HSI_VALUE;  // 0x80000000
    Ulong     DIV_mantissa = 0x00;
    Ulong     DIV_fraction = 0x00;
    float     div;
    
    tmp  = usart->CR2;
    tmp &= CR2_STOP_CLEAR_MASK;  //
    tmp |= (Ulong)type->USART_STOPBITS;  //
    usart->CR2 = (Uint)tmp;  // 0x40010810

    tmp  = usart->CR1;
    tmp &= CR1_CLEAR_MASK;   // 0xE9F3 : 1110100111110011
    tmp |= (Ulong)type->USART_WORDLENGTH |   // 0
                  type->USART_PARITY     |   // 0
                  type->USART_MODE;          // 1100
    usart->CR1 = (Uint)tmp;  // 0x4001080c | 1100
    
    tmp  = usart->CR3;       // 0x40010814
    tmp &= CR3_CLEAR_MASK;   // 0xFCFF : 1111110011111111
    tmp |= type->USART_HARDWAREFLOWCONTROL;
    usart->CR3 = (Uint)tmp;

    div = (float)apbclock / (type->USART_BAUDRATE<<4);
    DIV_mantissa = (Ulong)div << 4;
    tmp = DIV_mantissa;
    
    DIV_fraction = (Ulong)(((div - (Ulong)div) * 16 ) + 0.5);
    tmp |= (Ulong)DIV_fraction;

    usart->BRR = (Uint)tmp;
}

void USART_Init()
{
    USART_InitTypeDef  USART_InitStructure;
  
    USART_InitStructure.USART_BAUDRATE     = 115200;
    USART_InitStructure.USART_WORDLENGTH   = USART_WORDLENGTH_8B;
    USART_InitStructure.USART_STOPBITS     = USART_STOPBITS_1;
    USART_InitStructure.USART_PARITY       = USART_PARITY_NO;
    USART_InitStructure.USART_HARDWAREFLOWCONTROL 
                                           = USART_HARDWAREFLOWCONTROL_NONE;
    USART_InitStructure.USART_MODE         = USART_MODE_Rx | USART_MODE_Tx;

    // Set USART
    USARTSet(USART1, &USART_InitStructure);
    
    // Enable USART1
    USART1->CR1 |= CR1_UE_SET;
}

